import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
/**
 * class Server
 * 	 - listen to connect
 *   - start IO thread
 */
public class Server extends Thread {

	private ServerSocket serverSocket = null;
	private HashMap<Socket, PrintWriter> sockets;
	private Maze maze;
	private boolean isPS; // true: PS; false: BS;
	private int port;
	
	public Server(int m_MazeSize, int m_NrOfTreasures, boolean isPS) {
		maze = new Maze(m_MazeSize, m_NrOfTreasures);
		this.isPS = isPS;
	}
	
	public void run() {
		boolean listening = true;
		int clientnum = 0;
		
		sockets = new HashMap<Socket, PrintWriter>();
		
		if (isPS) {
			try {
				serverSocket = new ServerSocket(4701);
			} catch (IOException e1) {
				e1.printStackTrace();
				System.out.println("Could not listen on prot: 4701.");
				System.exit(-1);
			}
			maze.buildTreasure();
			// accept the first client
			while (listening) {
				try {
					Socket socket = serverSocket.accept();
					
					// start IO thread
					PrintWriter os = new PrintWriter(socket.getOutputStream());
					sockets.put(socket, os);
					new ServerIOThread(socket, sockets, clientnum, maze, isPS).start();
					clientnum ++;
					break;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			// accept other clients
			while (listening) {
				try {
					Socket socket = serverSocket.accept();
					
					// if the game has started, reject the connect
					if (TimeThread.getTime() >= 2000) {
						PrintWriter os = new PrintWriter(socket.getOutputStream());
						os.println("Sorry, the game has started");
						os.flush();
						os.close();
						socket.close();
						socket = null;
						continue;
						//break;
					}
					
					// TODO start IO thread
					PrintWriter os = new PrintWriter(socket.getOutputStream());
					sockets.put(socket, os);
					new ServerIOThread(socket, sockets, clientnum, maze, isPS).start();
					
					clientnum ++;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		else {
			// if this is a BS
			listening = false;
			int pt = 0;

			while (!listening) {
				try {
					pt = (int)(Math.random()*25000+4702);
					serverSocket = new ServerSocket(pt);
					listening = true;
				} catch (IOException e1) {
					e1.printStackTrace();
					System.out.println("Could not listen on prot: " + pt + ".");
					try {
						serverSocket.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
					serverSocket = null;
				}
			}
			port = pt;
			while (listening) {
				// only waiting for clients
				try {
					Socket socket = serverSocket.accept();
					
					PrintWriter os = new PrintWriter(socket.getOutputStream());
					sockets.put(socket, os);
					
					new ServerIOThread(socket, sockets, clientnum, maze, isPS).start();
					
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		
		}
		
		try {
			serverSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}
}
